import geopandas as gpd
import pandas as pd
import folium
from folium.plugins import HeatMap
import matplotlib.pyplot as plt
import contextily as ctx
import numpy as np
from shapely.geometry import Point

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# ====================== 1. 数据准备 ======================
data = {
    "District": ["浦东新区", "黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区",
                 "闵行区", "宝山区", "嘉定区", "金山区", "松江区", "青浦区", "奉贤区", "崇明区"],
    "Nursing_Homes": [25, 8, 12, 10, 9, 11, 7, 10, 15, 12, 10, 6, 8, 7, 6, 5],
    "Elderly_Beds": [12000, 8500, 9500, 4200, 8200, 4000, 5000, 7000, 7000, 5400, 5600, 3100, 3000, 3900, 2700, 1900],
    "Culture_Sites": [150, 120, 95, 80, 110, 75, 65, 85, 90, 70, 60, 45, 55, 50, 40, 30],
    "Green_Area": [3500, 850, 1200, 950, 800, 1100, 750, 900, 2800, 1800, 1600, 1400, 1500, 1300, 1200, 3000],
    "Longitude": [121.47, 121.48, 121.43, 121.42, 121.46, 121.39, 121.49, 121.52,
                  121.38, 121.48, 121.26, 121.34, 121.24, 121.12, 121.47, 121.40],
    "Latitude": [31.22, 31.23, 31.19, 31.21, 31.23, 31.25, 31.27, 31.27,
                 31.11, 31.40, 31.38, 30.75, 31.00, 31.15, 30.92, 31.62]
}

df = pd.DataFrame(data)
df['Elderly_Pop'] = [180, 60, 70, 50, 65, 75, 55, 80, 120, 90, 85, 40, 75, 50, 45, 30]
geometry = [Point(xy) for xy in zip(df['Longitude'], df['Latitude'])]
gdf = gpd.GeoDataFrame(df, geometry=geometry, crs="EPSG:4326")


# ====================== 2. 老年护理机构热力图 ======================
def nursing_homes_map():
    m = folium.Map(location=[31.23, 121.47], zoom_start=10, tiles='CartoDB positron')

    # 热力图
    HeatMap(
        data=df[['Latitude', 'Longitude', 'Nursing_Homes']].values,
        name='老年护理机构',
        gradient={0.2: 'blue', 0.4: 'lime', 0.6: 'orange', 1: 'red'},
        radius=25,
        blur=15
    ).add_to(m)

    # 添加标记
    for idx, row in df.iterrows():
        folium.CircleMarker(
            location=[row['Latitude'], row['Longitude']],
            radius=row['Nursing_Homes'] * 0.7,
            popup=f"{row['District']}<br>护理机构: {row['Nursing_Homes']}所",
            color='red',
            fill=True,
            fill_opacity=0.6
        ).add_to(m)

    folium.LayerControl().add_to(m)
    m.save('nursing_homes_map.html')
    return m


# ====================== 3. 文化设施热力图 ======================
def culture_sites_map():
    m = folium.Map(location=[31.23, 121.47], zoom_start=10, tiles='CartoDB positron')

    HeatMap(
        data=df[['Latitude', 'Longitude', 'Culture_Sites']].values,
        name='文化设施',
        gradient={0.2: 'lightblue', 0.5: 'purple', 0.8: 'darkblue'},
        radius=25,
        blur=15
    ).add_to(m)

    for idx, row in df.iterrows():
        folium.CircleMarker(
            location=[row['Latitude'], row['Longitude']],
            radius=row['Culture_Sites'] * 0.5,
            popup=f"{row['District']}<br>文化设施: {row['Culture_Sites']}处",
            color='blue',
            fill=True,
            fill_opacity=0.6
        ).add_to(m)

    m.save('culture_sites_map.html')
    return m


# ====================== 4. 绿地资源热力图 ======================
def green_area_map():
    m = folium.Map(location=[31.23, 121.47], zoom_start=10, tiles='CartoDB positron')

    HeatMap(
        data=df[['Latitude', 'Longitude', 'Green_Area']].values,
        name='绿地资源',
        gradient={0.2: 'lightgreen', 0.5: 'green', 0.8: 'darkgreen'},
        radius=30,
        blur=20
    ).add_to(m)

    for idx, row in df.iterrows():
        folium.CircleMarker(
            location=[row['Latitude'], row['Longitude']],
            radius=row['Green_Area'] / 200,
            popup=f"{row['District']}<br>绿地面积: {row['Green_Area']}公顷",
            color='green',
            fill=True,
            fill_opacity=0.7
        ).add_to(m)

    m.save('green_area_map.html')
    return m


# ====================== 5. 静态地图可视化 ======================
def plot_static_map(column, title, cmap, filename):
    fig, ax = plt.subplots(figsize=(10, 8))

    # 创建基础地图
    ax.set_xlim(121.1, 121.9)
    ax.set_ylim(30.7, 31.7)
    ctx.add_basemap(ax, crs="EPSG:4326", source=ctx.providers.CartoDB.Positron)

    # 绘制热力图
    sc = ax.scatter(
        x=df['Longitude'],
        y=df['Latitude'],
        c=df[column],
        s=df[column] * 3,
        cmap=cmap,
        alpha=0.7,
        edgecolors='white'
    )

    # 添加标注
    for idx, row in df.iterrows():
        ax.annotate(
            text=f"{row['District']}\n{row[column]:.0f}",
            xy=(row['Longitude'], row['Latitude']),
            ha='center',
            va='center',
            fontsize=8,
            bbox=dict(boxstyle="round", fc="white", ec="none", alpha=0.7)
        )

    plt.colorbar(sc, label=title)
    plt.title(f'上海{title}分布', fontsize=16)
    plt.axis('off')
    plt.tight_layout()
    plt.savefig(f'{filename}.png', dpi=300, bbox_inches='tight')
    plt.close()


# 生成静态地图
plot_static_map('Nursing_Homes', '老年护理机构', 'Reds', 'nursing_homes_static')
plot_static_map('Culture_Sites', '文化设施', 'Blues', 'culture_sites_static')
plot_static_map('Green_Area', '绿地资源', 'Greens', 'green_area_static')

# 生成交互式地图
nursing_map = nursing_homes_map()
culture_map = culture_sites_map()
green_map = green_area_map()